package com.crane.oss.sys.service.impl;


import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.crane.common.core.dto.SessUser;
import com.crane.common.framework.utils.BeanUtil;
import com.crane.oss.enums.UserTypeEnum;
import com.crane.oss.properties.SysConfigProperties;
import com.crane.oss.sys.bean.request.menu.AddOrUpdateMenuVueEleRequest;
import com.crane.oss.sys.bean.resp.MenuVueEleBean;
import com.crane.oss.sys.dao.MenuVueEleDao;
import com.crane.oss.sys.model.MenuVueEle;
import com.crane.oss.sys.service.MenuVueEleService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.*;

@Service("menuVueEleService")
public class MenuVueEleServiceImpl implements MenuVueEleService {

    private static final Logger logger = LoggerFactory.getLogger(MenuVueEleServiceImpl.class);

    @Resource
    protected MenuVueEleDao menuVueEleDao;

    @Resource
    protected SysConfigProperties sysConfigProperties;

    @Override
    public MenuVueEleBean queryMenuVueEleByMenuId(Long menuId) {
        logger.info("MenuVueEleServiceImpl queryMenuVueEleByMenuId menuId={}", menuId);
        MenuVueEleBean menuVueEleBean = null;
        MenuVueEle menuVueEle = menuVueEleDao.selectOne(Wrappers.lambdaQuery(MenuVueEle.class).eq(MenuVueEle ::getMenuId,menuId));
        if (null != menuVueEle) {
            menuVueEleBean = new MenuVueEleBean();
            _bulidMenuVueEleBean(menuVueEleBean, menuVueEle);
        }
        return menuVueEleBean;
    }

    @Override
    public MenuVueEleBean queryMenuVueTree(SessUser opUser) {
        logger.info("MenuVueEleServiceImpl queryMenuVueEleByUserId opUser={}", opUser.getUserName());
        Long userId = null;
        boolean isSuperAdmin = opUser.getUserType().equals(UserTypeEnum.SUPER_ADMIN.getType());
        if (!isSuperAdmin) {
            userId = opUser.getUserId();
        }
        MenuVueEleBean menuVueEleBean = new MenuVueEleBean();
        List<MenuVueEle> menuVueEleList = menuVueEleDao.queryMenuVueEleByUserId(userId);
        if (!isSuperAdmin || (isSuperAdmin && null == sysConfigProperties.getSysMenuIds())) {
            _getMenuTreeList(null, menuVueEleList, menuVueEleBean);
        } else {
            MenuVueEle parentMenuVueEle = menuVueEleDao.selectOne(Wrappers.lambdaQuery(MenuVueEle.class).eq(MenuVueEle ::getMenuId,sysConfigProperties.getDefaultMenuId()));
            _bulidMenuVueEleBean(menuVueEleBean, parentMenuVueEle);
            menuVueEleBean.setChildren(new ArrayList<MenuVueEleBean>());

            for (Long sysMenuId : sysConfigProperties.getSysMenuIds()) {
                MenuVueEleBean childTreeMenuBean = new MenuVueEleBean();
                menuVueEleBean.getChildren().add(childTreeMenuBean);
                MenuVueEle sysMenuVueEle = menuVueEleDao.selectOne(Wrappers.lambdaQuery(MenuVueEle.class).eq(MenuVueEle ::getMenuId,sysMenuId));
                _getMenuTreeList(sysMenuVueEle, menuVueEleList, childTreeMenuBean);
            }
        }

        return menuVueEleBean;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int save(AddOrUpdateMenuVueEleRequest addRequest) {
        logger.info("MenuVueEleServiceImpl save request={}", JSON.toJSON(addRequest));
        MenuVueEle menuVueEle = new MenuVueEle();
        BeanUtil.copyProperties(addRequest, menuVueEle);
        menuVueEle.setCreateTime(new Date());
        return menuVueEleDao.insert(menuVueEle);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int update(AddOrUpdateMenuVueEleRequest updateRequest) {
        logger.info("MenuVueEleServiceImpl update request={}", JSON.toJSON(updateRequest));
        MenuVueEle menuVueEle = menuVueEleDao.selectOne(Wrappers.lambdaQuery(MenuVueEle.class).eq(MenuVueEle ::getMenuId,updateRequest.getMenuId()));
        BeanUtil.copyProperties(updateRequest, menuVueEle);
        return menuVueEleDao.updateById(menuVueEle);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteMenuVueEleByMenuId(Long menuId) {
        logger.info("MenuVueEleServiceImpl deleteMenuVueEleByMenuId menuId={}", menuId);
        return menuVueEleDao.delete(Wrappers.lambdaUpdate(MenuVueEle.class).eq(MenuVueEle ::getMenuId,menuId));
    }

    /**
     * 构造树
     *
     * @param parentMenuVueEle 开始递归的节点
     * @param menuList         递归的数组
     * @param menuVueEleBean   返回的递归对象
     */
    private void _getMenuTreeList(MenuVueEle parentMenuVueEle, List<MenuVueEle> menuList, MenuVueEleBean menuVueEleBean) {
        if (null != parentMenuVueEle) {
            _bulidMenuVueEleBean(menuVueEleBean, parentMenuVueEle);
        }
        for (MenuVueEle menuVueEle : menuList) {
            // 如果没有指定父节点,默认从 0 开始查找
            if (null == parentMenuVueEle) {
                if (menuVueEle.getParentMenuId().equals(sysConfigProperties.getDefaultParentMenuId())) {
                    _getMenuTreeList(menuVueEle, menuList, menuVueEleBean);
                }
            } else if (menuVueEle.getParentMenuId().equals(parentMenuVueEle.getMenuId())) {

                MenuVueEleBean childTreeMenuBean = new MenuVueEleBean();
                // 建立父子关系
                if (null == menuVueEleBean.getChildren()) {
                    List<MenuVueEleBean> children = new ArrayList<>();
                    menuVueEleBean.setChildren(children);
                }
                menuVueEleBean.getChildren().add(childTreeMenuBean);
                _getMenuTreeList(menuVueEle, menuList, childTreeMenuBean);

            }
        }
        // 对自己节点进行排序
        if (!CollectionUtils.isEmpty(menuVueEleBean.getChildren())) {
            Collections.sort(menuVueEleBean.getChildren());
        }
    }

    private void _bulidMenuVueEleBean(MenuVueEleBean menuVueEleBean, MenuVueEle menuVueEle) {
        menuVueEleBean.setPath(menuVueEle.getPath());
        menuVueEleBean.setOrderNum(menuVueEle.getOrderNum());
        if (menuVueEle.getHidden().equals(0)) {
            menuVueEleBean.setHidden(false);
        } else {
            menuVueEleBean.setHidden(true);
        }
        menuVueEleBean.setRedirect(menuVueEle.getRedirect());
        menuVueEleBean.setComponent(menuVueEle.getComponent());
        menuVueEleBean.setName(menuVueEle.getName());
        menuVueEleBean.setType(menuVueEle.getType());
        Map<String, Object> meta = new HashMap<>();
        if (!StringUtils.isEmpty(menuVueEle.getMeta())) {
            meta = JSON.parseObject(menuVueEle.getMeta());
            menuVueEleBean.setMeta(meta);
        }

    }
}
